#!/usr/bin/python3
# -*- coding: utf-8 -*-
 
from PyQt5.QtWidgets import QWidget, QApplication
from PyQt5.QtGui import QPainter, QColor, QBrush
import sys
from data import game_table
import numpy as np
from PyQt5.QtWidgets import  QComboBox,QTableView,QAbstractItemView,QHeaderView,QTableWidget, QTableWidgetItem, QMessageBox,QListWidget,QListWidgetItem, QStatusBar,  QMenuBar,QMenu,QAction,QLineEdit,QStyle,QFormLayout,   QVBoxLayout,QWidget,QApplication ,QHBoxLayout, QPushButton,QMainWindow,QGridLayout,QLabel
from PyQt5.QtGui import QIcon,QPixmap,QStandardItem,QStandardItemModel,QCursor,QFont,QBrush,QColor,QPainter
from PyQt5.QtCore import QStringListModel,QAbstractListModel,QModelIndex,QSize,Qt,QObject,pyqtSignal,QTimer,QEvent
import copy
import random 

class  Snake:
    def __init__(self):
        self.length = 3
        self.head = 1
        self.type = 1
        self.x = 22
        self.y = 50
        self.step = 5
        self.score = 0 # 及时经验
        self.tscore = 0 # 累计经验
        self.color = '#ff0044'
        self.head_color = '#aa0044'
        # self.points = np.array([[0,0],[-1,0],[-2,0]])
        self.points = [[0,0],[-1,0],[-2,0]]
    def length_add1(self):
        self.length += 1
    

class  Food:
    def __init__(self, x, y, score=1):
        self.color = '#0FA07E'
        self.x = x
        self.y = y 
        self.score = score

class Example(QWidget):
    
    def __init__(self):
        super().__init__()
        d = np.transpose(np.array(game_table.game_map)[:,:100])
        self.map =  np.vstack((d,d[::-1,:]))#, np.array(game_table.game_map)[:,::-1])
        self.map_shape = self.map.shape
        self.map_t = 20
        self.food_t = 2

        self.initUI()
        self.self_snake = Snake()
        self.snakes = []
        self.initFoods()
        
        t = QTimer(self)
        t.timeout.connect(self.addFoods)
        t.start(1000)

        self.click_move = QTimer(self)
        self.click_move.timeout.connect(self.clickMove)

        # self.addFoods()
    
    def initFoods(self):
        self.foods = []
        t = 2
        w = (self.map_shape[0]*self.map_t)//t
        h = (self.map_shape[1]*self.map_t)//t
        for _ in range(h):
            self.foods.append([])
            for _ in range(w):
                self.foods[-1].append([])
        self.foods_list = []

    def initUI(self):      
        self.setGeometry(300, 300, 700, 500)
        self.setWindowTitle('Colours')
        self.show()
    
    def addFoods(self):
        x = random.randint(0, 500)
        y = random.randint(0, 700)
        # x = 100
        # y = 120
        self.foods_list.append([x, y])
        self.foods[y][x].append(Food(x, y))
        self.update()
 
    def paintEvent(self, e):

        self.w_w = self.geometry().width()
        self.w_h = self.geometry().height()

        self.s_x = (self.self_snake.x * self.self_snake.step) - self.w_w//2
        self.s_y = (self.self_snake.y * self.self_snake.step) - self.w_h//2

        print(self.self_snake.x, self.self_snake.y)
        self.s_s = int(self.self_snake.step * self.self_snake.type)


        qp = QPainter()
        qp.begin(self)
        self.drawMaps(qp)
        self.drawMinMaps(qp)
        self.drawSnake(qp)
        self.drawFoods(qp)
        qp.end()
    
    def removeFood(self, fpoint): #spoint
        pscore = 0 # 移除食物的分数
        pp = []
        # 删除地图映射数组的食物
        for fd in self.foods[fpoint[1]][fpoint[0]]:
            pscore += fd.score

        self.foods[fpoint[1]][fpoint[0]] = []
        
        # 获取食物的id
        if fpoint not in self.foods_list:
            return pscore
        p = self.foods_list.index(fpoint)
        pl = len(self.foods_list)
        while p >= 0 :
            pp.append(p)
            if  p > pl -2:
                break
            if fpoint not in self.foods_list[p + 1 :]:
                break
            p = self.foods_list[p + 1 :].index(fpoint)

        # 删除需要删除的食物
        ppl = len(pp)
        for i in range(ppl):
            self.foods_list.pop(pp[ppl-i-1])
        return pscore

    def drawFoods(self, qp):
        t = 2
        fs = self.foods_list
        for ft in fs:
            for f in self.foods[ft[1]][ft[0]]: 
                qp.drawRect(t*f.x-self.s_x, t*f.y -
                            self.s_y, t*f.score, t*f.score)

    def drawMaps(self, qp):
        t = self.map_t
        map_h = self.w_h // t 
        map_w = self.w_w // t
        map_x = self.s_x // t
        map_y = self.s_y // t
        for e, rows in enumerate(self.map): #[map_y:map_y+map_h]
            for f, cell in enumerate(rows): #[map_x: map_x+map_w]
                col = QColor(0, 0, 0)
                col.setNamedColor('#FF%XFF'%(255-0x10*cell))
                qp.setPen(col)
                qp.setBrush(col)
                qp.drawRect(e*t-self.s_x, f*t-self.s_y, t, t)

    def drawMinMaps(self, qp):
        t = 2
        starx = 20
        stary = 20
        col = QColor(0, 0, 0)
        for e, rows in enumerate(self.map):
            for f, cell in enumerate(rows):
                col.setNamedColor('#FF%XFF'%(255-0x10*cell))
                qp.setPen(col)
                qp.setBrush(col)
                qp.drawRect(e*t+starx,f*t+stary,t,t)

    def drawSnake(self, qp):
        t = self.self_snake.step
        points = np.array(self.self_snake.points)#+[self.self_snake.x,self.self_snake.y]

        # 画身体
        col = QColor(0, 0, 0)
        col.setNamedColor(self.self_snake.color)
        qp.setPen(col)
        qp.setBrush(col)
        for p in points[1:]:
            # qp.drawRect(t*p[0]-self.s_x//self.self_snake.step, t*p[1] -
            #             self.s_y//self.self_snake.step, t*self.self_snake.type, t*self.self_snake.type)
            qp.drawRect(self.w_w//2+t*p[0], self.w_h//2+t*p[1], t*self.self_snake.type, t*self.self_snake.type)

        # 画头部
        p  = points[0]
        col = QColor(0, 0, 0)
        col.setNamedColor(self.self_snake.head_color)
        qp.setPen(col)
        qp.setBrush(col)
        # qp.drawRect(t*p[0], t*p[1], t *
        #             self.self_snake.type, t*self.self_snake.type)
        qp.drawRect(self.w_w//2, self.w_h//2, t *
                    self.self_snake.type, t*self.self_snake.type)

    def snake_move(self, snake_point, move_dir):    
        p_l = len(snake_point)
        for p_i in range(p_l-1):
            p_p  = snake_point[p_l - p_i -1]
            p_p2  = snake_point[p_l - p_i -2]
            p_p[0] = p_p2[0]+move_dir[0]
            p_p[1] = p_p2[1] + move_dir[1]

        self.eat_food()
            
    def eat_food(self):
        food_t = self.food_t
        # 将蛇的坐标映射到食物空间
        x = (self.self_snake.x*self.self_snake.step)//food_t
        y = (self.self_snake.y * self.self_snake.step) // food_t
        s = int(self.self_snake.step * self.self_snake.type)
        
        for i in range(s):
            for j in range(s):
                score = self.removeFood([x + i, y + j])
                self.self_snake.score += score

    def keyPressEvent(self, QKeyEvent):#重写按键事件
        # points = self.self_snake.points
        move_dir = [0,0]
        if QKeyEvent.key()==Qt.Key_A:#按A建
            self.self_snake.x -= 1
            move_dir = [1,0]
        elif QKeyEvent.key()==Qt.Key_S:#按s建
            self.self_snake.y += 1
            move_dir = [0,-1]
        elif QKeyEvent.key()==Qt.Key_D:#按d建
            self.self_snake.x += 1
            move_dir = [-1,0]
        elif QKeyEvent.key()==Qt.Key_W:#按w建
            self.self_snake.y -= 1
            move_dir = [0,1]
        self.snake_move(self.self_snake.points, move_dir)
        self.update()
        self.move_trance = []

    def clickMove(self):
        if len(self.move_trance) <= 0:
            print('func stop')
            self.click_move.stop()
            return
        p = self.move_trance.pop(0)
        print(len(self.move_trance),p)
        self.self_snake.x += p[0]
        self.self_snake.y += p[1]
        ex = -p[0]
        ey = -p[1]
        self.snake_move(self.self_snake.points, [ex,ey])
        self.update()

    def mousePressEvent(self, event):
        if event.buttons () == Qt.LeftButton:                           # 左键按下
            # if self.click_move != None:
            
            self.move_trance = []
            if len(self.move_trance) != 0:
                print('click stop')
                self.click_move.stop()
            # self.setText ("单击鼠标左键的事件: 自己定义")
            click_x = event.windowPos().x()+self.s_x
            click_y = event.windowPos().y()+self.s_y
            print("单击鼠标左键,%d %d"%(click_x, click_y))  # 响应测试语句
            # 一条斜线
            st_x = click_x // self.self_snake.step
            st_y = click_y // self.self_snake.step
            print("当前， %d %d"%(self.self_snake.x, self.self_snake.y))
            print("目标, %d %d"%(st_x, st_y))  # 响应测试语句
            # pxy = (self.self_snake.x - st_x)/(self.self_snake.y - st_y)
            # t_x = -1 # 蛇预计的位置 x
            # te_x = 0
            # te_y = 0

            # for px in range(abs(int(st_x-self.self_snake.x))):
            #     self.move_trance.append([px-t_x, 0])
            #     t_y = -1 # 蛇预计的位置 y
            #     py = -1
            #     for py in range(abs(int(pxy*(px-te_x)))):
            #         self.move_trance.append([0, py-t_y])
            #         t_y = py
            #     if py >= 0:
            #         te_x = t_x
            #     t_x = px 
            sy_x = st_x-self.self_snake.x
            for _ in range(int(abs(sy_x))):
                if sy_x>0:
                    dir = [1,0]
                else:
                    dir = [-1,0]
                self.move_trance.append(dir)
            sy_y = st_y-self.self_snake.y
            for _ in range(int(abs(sy_y))):
                if sy_y>0:
                    dir = [0,1]
                else:
                    dir = [0,-1]
                self.move_trance.append(dir)

            print('move list:',len(self.move_trance),self.move_trance)
            # return 
            self.click_move.start(2)

        elif event.buttons () == Qt.RightButton:                        # 右键按下
            # self.setText ("单击鼠标右键的事件: 自己定义")
            print("单击鼠标右键")  # 响应测试语句
        elif event.buttons () == Qt.MidButton:                          # 中键按下
            # self.setText ("单击鼠标中键的事件: 自己定义")
            print("单击鼠标中键")  # 响应测试语句
        elif event.buttons () == Qt.LeftButton | Qt.RightButton: # 左右键同时按下
            # self.setText ("同时单击鼠标左右键的事件: 自己定义")
            print("单击鼠标左右键")  # 响应测试语句
        elif event.buttons () == Qt.LeftButton | Qt.MidButton:   # 左中键同时按下
            # self.setText ("同时单击鼠标左中键的事件: 自己定义")
            print("单击鼠标左中键")  # 响应测试语句
        elif event.buttons () == Qt.MidButton | Qt.RightButton:  # 右中键同时按下
            # self.setText ("同时单击鼠标右中键的事件: 自己定义")
            print("单击鼠标右中键")  # 响应测试语句
        elif event.buttons () == Qt.LeftButton | Qt.MidButton \
             | Qt.RightButton:                                          # 左中右键同时按下
            # self.setText ("同时单击鼠标左中右键的事件: 自己定义")
            print("单击鼠标左中右键")  # 响应测试语句
 
    
    
if __name__ == '__main__':
    app = QApplication(sys.argv)
    ex = Example()
    sys.exit(app.exec_())
